package ocbn.remotelab.events;

import ocbn.remotelab.util.Enum;
import ocbn.remotelab.util.date.*;

/**
 * An child class of Event that represents an event reporting the state of the
 * mass spectrometer
 *
 * @author Ke Li
 */
public class MassSpectrometerStateEvent extends Event {

    /**
     * The default event ID
     */
    private static final long DEFAULT_ID = Long.MIN_VALUE;
    /**
     * The default name of the equipment that generated this event
     */
    private static final String DEFAULT_SOURCE = "unknown mass spectrometer";
    /**
     * The default state of the equipment that generated this event
     */
    private static final State DEFAULT_STATE = State.UNKNOWN;
    /**
     * The mass spectrometer that generated this event
     */
    private String source;
    /**
     * The state of the mass spectrometer
     */
    private State state;

    /**
     * A class simulating an enumerated type that represents all the possible
     * states of the mass spectrometer
     */
    public static final class State extends Enum {

        /**
         * All the possible states of the mass spectrometer
         */
        public static final State STARTED
                = new State("STARTED", "Sample analysis started", false);
        public static final State COMPLETED
                = new State("COMPLETED", "Sample analysis completed "
                + "successfully", false);
        public static final State FAILED
                = new State("FAILED", "Sample analysis failed", true);
        /**
         * The default state when no information about the state is given. 
         */
        public static final State UNKNOWN
                = new State("UNKNOWN", "An unknown event occured", false);
        /**
         * A String containing the description of the state
         */
        private final String description;
        /**
         * A boolean indicating whether events in this state should be important
         */
        private final boolean isImportant;
        /**
         * Constructs an instance of State from the name, the description and
         * the importance.
         *
         * @param name          A String containing the name of the State object
         * @param description   A String containing the description of the State
         * @param isImportant   A boolean indicating whether events in this
         *                      State is considered important
         */
        State(String name, String description, boolean isImportant) {
            super(name);
            this.description = description;
            this.isImportant = isImportant;
        }

        /**
         * Converts the State to a String. 
         *
         * @return  A String representation of this State
         */
        public String toString() {
            return description;
        }

        /**
         * Retrieves a State instance by its name. 
         *
         * @param name  The name of the desired State instance
         * @return      The State instance if it is found, otherwise null
         */
        public static Enum valueOf(String name) {
            Enum tempEnum = Enum.valueOf(name);
            if(tempEnum == null) {
                return UNKNOWN;        // Not found
            } else {
                return tempEnum;
            }
        }
    };

    /**
     * Constructs an instance from the ID, time, source, state and details.
     *
     * @param id        The ID of the event
     * @param time      A Date object representing the time when the event
     *                  occured
     * @param source    A String containing the name of the source equipment
     *                  that generated the event
     * @param state     A State object representing the state of the equipment
     * @param details   A String containing detailed information about the event
     */
    public MassSpectrometerStateEvent(long id, State state, String source,
            Date time, String details) {
        super(id, time);
        setSource(source);
        setState(state);
        setDetails(details);
    }

    /**
     * Constructs an instance from the ID, time, source and state. The event
     * details is set to the event summary.
     *
     * @param id        The ID of the event
     * @param time      A Date object representing the time when the event
     *                  occured
     * @param source    A String containing the name of the source equipment
     *                  that generated the event
     * @param state     A State object representing the state of the equipment
     */
    public MassSpectrometerStateEvent(long id, State state, String source,
            Date time) {
        this(id, state, source, time, "");
    }

    /**
     * Constructs an instance from the ID, source and state. The event
     * details is set to the event summary and the time is set to the current
     * time.
     *
     * @param id        The ID of the event
     * @param source    A String containing the name of the source equipment
     *                  that generated the event
     * @param state     A State object representing the state of the equipment
     */
    public MassSpectrometerStateEvent(long id, State state, String source) {
        this(id, state, source, new Date());
    }

    /**
     * Constructs an instance from the ID and the state. The source is set to
     * "unknown mass spectrometer".
     *
     * @param id        The ID of the event
     * @param source    A String containing the name of the source equipment
     *                  that generated the event
     */
    public MassSpectrometerStateEvent(long id, State state) {
        this(id, state, DEFAULT_SOURCE);
    }

    /**
     * Constructs an instance from the ID only. The state is set to unknown.
     *
     * @param id    The ID of the event
     */
    public MassSpectrometerStateEvent(long id) {
        this(id, DEFAULT_STATE);
    }

    /**
     * Constructs an instance. The ID is set to the minimum value of a long
     * integer.
     */
    public MassSpectrometerStateEvent() {
        this(DEFAULT_ID);
    }

    /**
     * Retrieves the name of the mass spectrometer that generated this event.
     *
     * @return  A String containing the name of the source equipment
     */
    public String getSource() {
        return source;
    }

    /**
     * Sets the mass spectrometer that generated this event.
     *
     * @param source    A String containing the name of the source equipment
     */
    public void setSource(String source) {
        this.source = source;
    }

    /**
     * Retrieves the state of the mass spectrometer.
     *
     * @return  A State object representing the state of the equipment
     */
    public State getState() {
        return state;
    }

    /**
     * Sets the state of the mass spectrometer.
     *
     * @param state     A State object representing the state of the equipment
     */
    public void setState(State state) {
        this.state = state;
        setImportance(this.state.isImportant);
    }

    /**
     * Retrieves an automatically-generated summary of the event.
     *
     * @return  A String containing the summary
     */
    public String getSummary() {
        return state + " on " + getSource() + ". ";
    }

    /**
     * Retrieves detailed information about the event. If it is unavailable, the
     * automatically-generated summary is returned.
     *
     * @return  A String containing the details
     */
    public String getDetails() {
        if (!this.hasDetails()) {
            return getSummary();
        } else {
            return super.getDetails();
        }
    }

    /**
     * Converts this event to String. 
     *
     * @return  A String containing information about this object
     */
    public String toString() {
        return getSummary();
    }
}
